package com.burke.gwt.client;

/**
 * Displays a clock that counts down days/hours/minutes/seconds until the Google I/O conference.
 * As the clock changes, little floating androids fly over to the "jumping" developer.  This 
 * causes the developer to get more excited, and jump faster!  
 * 
 * Uses GWT and canvas component.  Uses a timer to handle animation loop.  Heavily influenced by
 * Google's GWT html5 examples.
 * 
 * Note: Code was done on Friday night after a trip to the bar.  It is not as elegant as it 
 * should be, but it was fun throwing it together ;-)
 *
 * @auther Thomas Burke (thomas.d.burke@gmail.com)
 */


import java.util.Date;

import com.google.gwt.canvas.client.Canvas;
import com.google.gwt.canvas.dom.client.Context2d;
import com.google.gwt.canvas.dom.client.CssColor;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.dom.client.ImageElement;
import com.google.gwt.dom.client.Touch;
import com.google.gwt.event.dom.client.GestureStartEvent;
import com.google.gwt.event.dom.client.GestureStartHandler;
import com.google.gwt.event.dom.client.MouseMoveEvent;
import com.google.gwt.event.dom.client.MouseMoveHandler;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOutHandler;
import com.google.gwt.event.dom.client.TouchEndEvent;
import com.google.gwt.event.dom.client.TouchEndHandler;
import com.google.gwt.event.dom.client.TouchMoveEvent;
import com.google.gwt.event.dom.client.TouchMoveHandler;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class Excitement implements EntryPoint {
	
	Canvas canvas;
	Canvas backBuffer;
	PersonGroup personGroup;
	FloaterGroup floaterGroup;
	
	static final String holderId = "canvasholder";
	
	// mouse positions relative to canvas
	int mouseX, mouseY;

	//timer refresh rate, in milliseconds
	static final int refreshRate = 25;
	
	// canvas size, in px
//	static final int height = 400;
//	static final int width = 400;
	int height;
	int width; 
	
	final CssColor redrawColor = CssColor.make("rgba(208,208,208,0.6)");
	Context2d context;
	Context2d backBufferContext;
	Clock clock;

    static final String upgradeMessage = "Your browser does not support the HTML5 Canvas. Please upgrade your browser to view this demo.";


	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad() {

		    canvas = Canvas.createIfSupported();
		    backBuffer = Canvas.createIfSupported();
		    if (canvas == null) {
		      RootPanel.get(holderId).add(new Label(upgradeMessage));
		      return;
		    }
		    width = RootPanel.get("canvasWrapper").getOffsetWidth();
		    height = RootPanel.get("canvasWrapper").getOffsetHeight();
		    
		    // init the canvases
		    canvas.setWidth(width + "px");
		    canvas.setHeight(height + "px");
		    canvas.setCoordinateSpaceWidth(width);
		    canvas.setCoordinateSpaceHeight(height);
		    backBuffer.setCoordinateSpaceWidth(width);
		    backBuffer.setCoordinateSpaceHeight(height);
		    

		    RootPanel.get("canvasWrapper").add(canvas);
		    context = canvas.getContext2d();
		    backBufferContext = backBuffer.getContext2d();
		    
		    personGroup = new PersonGroup(width, height, 10);
		    floaterGroup = new FloaterGroup(width, height);
		    
		  //Remove hard-coded date
            Date stop = new Date(new Date().getYear(),4,10,9,0,0);
            
            //create the Clock
            clock = new Clock(stop, floaterGroup);
		    

		    // init handlers
		    initHandlers();
		    
		    // setup timer
		    final Timer timer = new Timer() {
		      @Override
		      public void run() {
		        doUpdate();
		      }
		    };
		    timer.scheduleRepeating(refreshRate);
		  }

		  private ImageElement groupOfPeople = new Image("../group-of-people.png").getElement().cast();
		  private ImageElement directions = new Image("../mouse-over-message3.png").getElement().cast();
	
		  void doUpdate() {
		    // update the back canvas
		    backBufferContext.setFillStyle(redrawColor);
		    backBufferContext.fillRect(0, 0, width, height);

		    // draw the directions
		    backBufferContext.drawImage(directions, 420, 195);

		    //This is where i draw the background people
		    for(int i=0;i<Window.getClientWidth();i+=600) {
//		    	i + i*groupOfPeople.getWidth();
		    	backBufferContext.drawImage(groupOfPeople, i, height-171-30);
		    }
		    
		    
		    clock.update( (Window.getClientWidth() - 1000)/2, 50  );
		    personGroup.update(mouseX, mouseY);
		
		    floaterGroup.update(personGroup.targetPerson);
		    
		    clock.draw(backBufferContext);
		    personGroup.draw(backBufferContext);
		    floaterGroup.draw(backBufferContext);

		    context.drawImage(backBufferContext.getCanvas(), 0, 0);

		  }
		  
		  // The next 4 methods are copied from Google's examples
		  
		  void initHandlers() {
		    canvas.addMouseMoveHandler(new MouseMoveHandler() {
		      public void onMouseMove(MouseMoveEvent event) {
		        mouseX = event.getRelativeX(canvas.getElement());
		        mouseY = event.getRelativeY(canvas.getElement());
		      }
		    });

		    canvas.addMouseOutHandler(new MouseOutHandler() {
		      public void onMouseOut(MouseOutEvent event) {
		        mouseX = -200;
		        mouseY = -200;
		      }
		    });

		    canvas.addTouchMoveHandler(new TouchMoveHandler() {
		      public void onTouchMove(TouchMoveEvent event) {
		        event.preventDefault();
		        if (event.getTouches().length() > 0) {
		          Touch touch = event.getTouches().get(0);
		          mouseX = touch.getRelativeX(canvas.getElement());
		          mouseY = touch.getRelativeY(canvas.getElement());
		        }
		        event.preventDefault();
		      }
		    });

		    canvas.addTouchEndHandler(new TouchEndHandler() {
		      public void onTouchEnd(TouchEndEvent event) {
		        event.preventDefault();
		        mouseX = -200;
		        mouseY = -200;
		      }
		    });

		    canvas.addGestureStartHandler(new GestureStartHandler() {
		      public void onGestureStart(GestureStartEvent event) {
		        event.preventDefault();
		      }
		    });
		  }
		  
}
